/**
  ******************************************************************************
  * @file    IIC.c
  * @author  Dajin Li
  * @version V0.0.1
  * @date    08-08-2015 
  * @brief   This file contains IIC read/write  function
  *          
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; KION(SZ) R&D Center
  *
  * Licensed under KION, (the "License");
  *
  ******************************************************************************
  */
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "global.h"
#include "spi.h"
//#include "hourmeter.h"
#include "can.h"
#include "var_tbl.h"
//#include "bdi.h"
//#include "pwm.h"
//#include "menu.h"
#include "lcd.h"
//#include "analoginput.h"
//#include "canJ1939.h"
//#include "menu.h"

/* Functions ------------------------------------------------------------------*/
static void EE_SPI_LowLevel_Init(void);
static uint8_t EE_SPI_ReadByte(void);
static uint8_t EE_SPI_SendByte(uint8_t byte);
static void EE_SPI_WriteEnable(void);
static void EE_SPI_WaitForWriteEnd(void);

/**
  * @brief  Initializes the peripherals used by the SPI eeprom driver.
  * @param  None
  * @retval None
  */
void EE_SPI_LowLevel_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    SPI_I2S_DeInit(EE_SPI);

    /*!< Enable the SPI clock */
    RCC_APB1PeriphClockCmd(EE_SPI_CLK, ENABLE);

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        
    /*!< SPI SCK pin configuration */
    GPIO_InitStructure.GPIO_Pin = EE_SPI_SCK_PIN | EE_SPI_MOSI_PIN | EE_SPI_MISO_PIN;
    GPIO_Init(EE_SPI_GPIO_PORT, &GPIO_InitStructure);

    /*!< Configure EE Card CS pin in output pushpull mode ********************/
    GPIO_InitStructure.GPIO_Pin = EE_SPI_CS_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(EE_SPI_GPIO_PORT, &GPIO_InitStructure);
}
/**
* @brief	spi init
* @param	none
* @note     none
* @retval   none
*/
void  EE_SPI_Init(void)
{
    SPI_InitTypeDef  SPI_InitStructure;

    EE_SPI_LowLevel_Init();

    /*!< Deselect the EE: Chip Select high */
    EE_SPI_CS_HIGH();

    /*!< SPI configuration , SPI mode 3*/
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;

    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(EE_SPI, &SPI_InitStructure);

    /*!< Enable the sFLASH_SPI  */
    SPI_Cmd(EE_SPI, ENABLE);
}
/**
  * @brief  Reads a byte from the SPI EE.
  * @note   This function must be used only if the Start_Read_Sequence function
  *         has been previously called.
  * @param  None
  * @retval Byte Read from the SPI EE.
  */
uint8_t EE_SPI_ReadByte(void)
{
    return (EE_SPI_SendByte(EE_SPI_DUMMY_BYTE));
}
/**
  * @brief  Sends a byte through the SPI interface and return the byte received
  *         from the SPI bus.
  * @param  byte: byte to send.
  * @retval The value of the received byte.
  */
uint8_t EE_SPI_SendByte(uint8_t byte)
{
    /*!< Loop while DR register in not emplty */
    while (SPI_I2S_GetFlagStatus(EE_SPI, SPI_I2S_FLAG_TXE) == RESET);

    /*!< Send byte through the SPI1 peripheral */
    SPI_I2S_SendData(EE_SPI, byte);

    /*!< Wait to receive a byte */
    while (SPI_I2S_GetFlagStatus(EE_SPI, SPI_I2S_FLAG_RXNE) == RESET);

    /*!< Return the byte read from the SPI bus */
    return SPI_I2S_ReceiveData(EE_SPI);
}

/**
  * @brief  Enables the write access to the EE.
  * @param  None
  * @retval None
  */
void EE_SPI_WriteEnable(void)
{
    /*!< Select the EE: Chip Select low */
    EE_SPI_CS_LOW();

    /*!< Send "Write Enable" instruction */
    EE_SPI_SendByte(EE_SPI_CMD_WREN);

    /*!< Deselect the EE: Chip Select high */
    EE_SPI_CS_HIGH();
}
/**
  * @brief  Polls the status of the Write In Progress (WIP) flag in the EE's
  *         status register and loop until write opertaion has completed.
  * @param  None
  * @retval None
  */
void EE_SPI_WaitForWriteEnd(void)
{
    uint8_t eetatus = 0;

    /*!< Select the EE: Chip Select low */
    EE_SPI_CS_LOW();

    /*!< Send "Read Status Register" instruction */
    EE_SPI_SendByte(EE_SPI_CMD_RDSR);

    /*!< Loop as long as the memory is busy with a write cycle */
    do
    {
        /*!< Send a dummy byte to generate the clock needed by the EE
        and put the value of the status register in FLASH_Status variable */
        eetatus = EE_SPI_SendByte(EE_SPI_DUMMY_BYTE);

    }
    while ((eetatus & EE_SPI_WIP_FLAG) == 0x02); /* Write in progress */

    /*!< Deselect the EE: Chip Select high */
    EE_SPI_CS_HIGH();
}
/**
  * @brief  Reads a block of data from the EE.
  * @param  pBuffer: pointer to the buffer that receives the data read from the EE.
  * @param  ReadAddr: EE's internal address to read from.
  * @param  NumByteToRead: number of bytes to read from the EE.
  * @retval None
  */
void EE_SPI_ReadBuffer(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead)
{
    /*!< Select the EE: Chip Select low */
    EE_SPI_CS_LOW();

    /*!< Send "Read from Memory " instruction */
    EE_SPI_SendByte(EE_SPI_CMD_READ);

    /*!< Send ReadAddr high nibble address byte to read from */
    EE_SPI_SendByte((ReadAddr& 0xFF00) >> 8);
    /*!< Send ReadAddr low nibble address byte to read from */
    EE_SPI_SendByte(ReadAddr & 0xFF);

    while (NumByteToRead--) /*!< while there is data to be read */
    {
        /*!< Read a byte from the EE */
        *pBuffer = EE_SPI_ReadByte();
        /*!< Point to the next location where the byte read will be saved */
        pBuffer++;
    }

    /*!< Deselect the EE: Chip Select high */
    EE_SPI_CS_HIGH();
}
/**
  * @brief  Writes block of data to the EE. In this function, the number of
  *         WRITE cycles are reduced, using Page WRITE sequence.
  * @param  pBuffer: pointer to the buffer  containing the data to be written
  *         to the EE.
  * @param  WriteAddr: EE's internal address to write to.
  * @param  NumByteToWrite: number of bytes to write to the EE.
  * @retval None
  */
void EE_SPI_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite)
{
    /*!< Enable the write access to the EE */
    EE_SPI_WriteEnable();

    /*!< Select the EE: Chip Select low */
    EE_SPI_CS_LOW();
    /*!< Send "Write to Memory " instruction */
    EE_SPI_SendByte(EE_SPI_CMD_WRITE);
    /*!< Send WriteAddr high address byte to write to */
    EE_SPI_SendByte((WriteAddr & 0xFF00) >> 8);
    /*!< Send WriteAddr low nibble address byte to write to */
    EE_SPI_SendByte(WriteAddr & 0xFF);

    /*!< while there is data to be written on the EE */
    while (NumByteToWrite--)
    {
        /*!< Send the current byte */
        EE_SPI_SendByte(*pBuffer);
        /*!< Point on the next byte to be written */
        pBuffer++;
    }

    /*!< Deselect the EE: Chip Select high */
    EE_SPI_CS_HIGH();

    /*!< Wait the end of EE writing */
    EE_SPI_WaitForWriteEnd();
}

/**
  * @brief  Writes block of data to the EE. In this function, the number of
  *         WRITE cycles are reduced, using Page WRITE sequence.
  * @param  pBuffer: pointer to the buffer  containing the data to be written
  *         to the EE.
  * @param  WriteAddr: EE's internal address to write to.
  * @param  NumByteToWrite: number of bytes to write to the EE.
  * @retval None
  */
void EE_SPI_Write_Fixed_Data(uint8_t data, uint16_t WriteAddr, uint16_t NumByteToWrite)
{
    /*!< Enable the write access to the EE */
    EE_SPI_WriteEnable();

    /*!< Select the EE: Chip Select low */
    EE_SPI_CS_LOW();
    /*!< Send "Write to Memory " instruction */
    EE_SPI_SendByte(EE_SPI_CMD_WRITE);
    /*!< Send WriteAddr high address byte to write to */
    EE_SPI_SendByte((WriteAddr & 0xFF00) >> 8);
    /*!< Send WriteAddr low nibble address byte to write to */
    EE_SPI_SendByte(WriteAddr & 0xFF);

    /*!< while there is data to be written on the EE */
    while (NumByteToWrite--)
    {
        /*!< Send the current byte */
        EE_SPI_SendByte(data);
    }

    /*!< Deselect the EE: Chip Select high */
    EE_SPI_CS_HIGH();

    /*!< Wait the end of EE writing */
    EE_SPI_WaitForWriteEnd();
}

/**
* @brief	initialize  parameter 
* @param	none
* @note     none
* @retval   none
*/
void ParaInit(void)
{   
//    u8 i = 0;
//    u32 temp_data = BIT0;

//    total_osha_msg = 0;
//    temp_data = BIT0;
//    for(i = 0; i < 32; i++)
//    {
//        if(active_osha_1 & temp_data)
//        {
//            osha_msg_show_index[total_osha_msg] = i;
//            total_osha_msg++;
//        }
//        temp_data <<= 1;
//    }
//    temp_data = BIT0;
//    for(i = 0; i < 8; i++)
//    {
//        if(active_osha_2 & temp_data)
//        {
//            osha_msg_show_index[total_osha_msg] = 32+i;
//            total_osha_msg++;
//        }
//        temp_data <<= 1;
//    }
//    max_traction_speed_data = max_traction_speed_value;
//    max_engine_speed_data = max_engine_speed_value;   
//    min_engine_speed_data = min_engine_speed_value;    

//    max_traction_speed_kp_data = max_traction_speed_kp;
//    max_traction_speed_ki_data = max_traction_speed_ki;
//    max_traction_speed_kd_data = max_traction_speed_kd;
//    
//	lcd_bklight_data = LCD_Bklight;

//    lcd_bklight_pwm = (u16)lcd_bklight_data * BKLIGHT_MAX;
//    if(lcd_bklight_pwm > 0)
//    {
//        lcd_bklight_pwm -= 1;
//    }

//    service_hours1 = Hrm_Struct.Service_hours1;
//    service_hours2 = Hrm_Struct.Service_hours2;
//    service_hours3 = Hrm_Struct.Service_hours3;
//    service_hours4 = Hrm_Struct.Service_hours4;

//    service_days1 = Hrm_Struct.Service_days1;
//    service_days2 = Hrm_Struct.Service_days2;
//    service_days3 = Hrm_Struct.Service_days3;
//    service_days4 = Hrm_Struct.Service_days4;

//    Hrm_Struct.Pre_service_hours1 = Hrm_Struct.Service_hours1;
//    Hrm_Struct.Pre_service_hours2 = Hrm_Struct.Service_hours2;
//    Hrm_Struct.Pre_service_hours3 = Hrm_Struct.Service_hours3;
//    Hrm_Struct.Pre_service_hours4 = Hrm_Struct.Service_hours4;

//    Hrm_Struct.Pre_service_days1 = Hrm_Struct.Service_days1;
//    Hrm_Struct.Pre_service_days2 = Hrm_Struct.Service_days2;
//    Hrm_Struct.Pre_service_days3 = Hrm_Struct.Service_days3;
//    Hrm_Struct.Pre_service_days4 = Hrm_Struct.Service_days4;

//    Hrm_Struct.Pre_HM1_value = Hrm_Struct.HM1_value;
//    Hrm_Struct.Pre_HM2_value = Hrm_Struct.HM2_value;
//    Hrm_Struct.Pre_HM3_value = Hrm_Struct.HM3_value;

//    speedometer_units_data = speedometer_units;
//    LanguageSelect_data = LanguageSelect;

//    status_select1_data = status_select1;
//    status_select2_data = status_select2;

//    date_format_data = date_format;

//    hour_format_12H = date_format;

//    fuel_sensor_type_data = fuel_sensor_type;
//    creep_speed_data = creep_speed;
//    display_options_data = display_options;
//    seatBeltData = seatBelt;

//    if((truck_type != BR1219) && (truck_type != BR1319) && (truck_type != BR1347))
//    {
//        display_options = 0;
//        display_options |= TRAVEL_SPD_DISP;
//    }
//    
//    Menu_st_init();    
}


